﻿' Frowser - http://www.frowser.net
' Copyright (c) 2010
' by Will Morgenweck, Active Modules, Inc.
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
' DEALINGS IN THE SOFTWARE.
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Web.Script.Services
Imports Newtonsoft.Json
Imports Frowser.Controllers
Namespace Frowser.Services
    <System.Web.Script.Services.ScriptService()> _
    <System.Web.Services.WebService(Namespace:="http://dnnforums.frowser.net/")> _
    <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <ToolboxItem(False)> _
    Public Class DNNForums
        Inherits WebServiceBase
        <WebMethod()> _
          <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function Forums(ByVal authtoken As String, ByVal Username As String, ByVal Password As String) As String
            Try
                Dim auth As New SecureHeader(authtoken, username, password)

                Dim isValid As Boolean = IsUserValid(auth)
                Dim sb As New StringBuilder
                Dim fc As New Controllers.DNNForums
                Try
                    Dim forumList As List(Of ForumInfo) = fc.ForumsList(PortalId, ModuleId, CurrentUser)
                    If forumList Is Nothing Then
                        Return BuildResult(String.Empty, ResultCodes.SuccessNoRecords, OutputTypes.JSON, False)
                    End If
                    If forumList.Count = 0 Then
                        Return BuildResult(String.Empty, ResultCodes.SuccessNoRecords, OutputTypes.JSON, False)
                    End If
                    For Each f As ForumInfo In forumList
                        sb.Append(JsonConvert.SerializeObject(f, Formatting.None))
                        sb.Append(",")
                    Next
                Catch ex As Exception
                    DotNetNuke.Services.Exceptions.LogException(ex)
                    Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
                End Try
                If sb.ToString.EndsWith(",") Then
                    sb.Remove(sb.Length - 1, 1)
                End If
                Return BuildResult(sb.ToString, ResultCodes.Success, OutputTypes.JSON, True)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
        <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function Topics(ByVal authtoken As String, ByVal Username As String, ByVal Password As String, ByVal ForumId As Integer, ByVal RowIndex As Integer, ByVal Rows As Integer) As String
            Try
                Dim auth As New SecureHeader(authtoken, Username, Password)
                If ForumId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                Dim sb As New StringBuilder
                Dim isValid As Boolean = IsUserValid(auth)
                Dim db As New Controllers.DNNForums
                Dim tl As List(Of ContentInfo) = db.GetTopics(PortalId, ModuleId, ForumId, CurrentUser, RowIndex, Rows)
                If tl Is Nothing Then
                    Return BuildResult(String.Empty, ResultCodes.SuccessNoRecords, OutputTypes.JSON, False)
                End If
                For Each t As ContentInfo In tl
                    sb.Append(JsonConvert.SerializeObject(t, Formatting.None))
                    sb.Append(",")
                Next
                If sb.ToString.EndsWith(",") Then
                    sb.Remove(sb.Length - 1, 1)
                End If
                Return BuildResult(sb.ToString, ResultCodes.Success, OutputTypes.JSON, True)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
        <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function Topic(ByVal authtoken As String, ByVal Username As String, ByVal Password As String, ByVal ForumId As Integer, ByVal TopicId As Integer, ByVal RowIndex As Integer, ByVal Rows As Integer) As String
            Try
                Dim auth As New SecureHeader(authtoken, Username, Password)

                If ForumId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                If TopicId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                Dim sb As New StringBuilder
                Dim isValid As Boolean = IsUserValid(auth)
                Dim db As New Controllers.DNNForums
                Dim tl As List(Of ContentInfo) = db.GetTopic(PortalId, ModuleId, ForumId, TopicId, CurrentUser, RowIndex, Rows)
                If tl Is Nothing Then
                    Return BuildResult(String.Empty, ResultCodes.SuccessNoRecords, OutputTypes.JSON, False)
                End If
                For Each t As ContentInfo In tl
                    sb.Append(JsonConvert.SerializeObject(t, Formatting.None))
                    sb.Append(",")
                Next
                If sb.ToString.EndsWith(",") Then
                    sb.Remove(sb.Length - 1, 1)
                End If
                Return BuildResult(sb.ToString, ResultCodes.Success, OutputTypes.JSON, True)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
      <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function Login(ByVal username As String, ByVal password As String) As String
            Try
                Return AuthenticateUser(username, password)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
     <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function GetSite() As String
            Try
                Init()
                Dim sb As New StringBuilder
                sb.Append("{")
                sb.Append(Utilities.JSON.Pair("sitename", PortalName))
                sb.Append(",")
                sb.Append(Utilities.JSON.Pair("siteid", PortalId.ToString))
                sb.Append(",")
                sb.Append(Utilities.JSON.Pair("servicepath", ServicePath))
                sb.Append("}")
                Return BuildResult(sb.ToString, ResultCodes.Success, OutputTypes.JSON, True)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function Reply(ByVal authtoken As String, ByVal Username As String, ByVal Password As String, ByVal ForumId As Integer, ByVal TopicId As Integer, ByVal body As String) As String
            Try
                Dim auth As New SecureHeader(authtoken, Username, Password)
                If ForumId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                If TopicId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                Dim isValid As Boolean = IsUserValid(auth)
                If Not isValid Then
                    Return BuildResult(String.Empty, ResultCodes.FailedAuthentication, OutputTypes.JSON, False)
                End If
                body = Active.Modules.Forums.Utilities.XSSFilter(body, True)
                Return BuildResult(String.Empty, ResultCodes.Success, OutputTypes.JSON, True)
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try

        End Function
        <WebMethod()> _
 <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function GetUser(ByVal authtoken As String, ByVal Username As String, ByVal Password As String, ByVal userId As Integer) As String
            Try
                Dim auth As New SecureHeader(authtoken, Username, Password)
                If userId = -1 Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                End If
                Dim isValid As Boolean = IsUserValid(auth)
                If Not isValid Then
                    Return BuildResult(String.Empty, ResultCodes.FailedAuthentication, OutputTypes.JSON, False)
                End If
                Dim uc As New DotNetNuke.Entities.Users.UserController
                Dim userInfo As DotNetNuke.Entities.Users.UserInfo = uc.GetUser(PortalId, userId)
                If userInfo Is Nothing Then
                    Return BuildResult(String.Empty, ResultCodes.FailedInvalidData, OutputTypes.JSON, False)
                Else
                    Return BuildResult(JsonConvert.SerializeObject(userInfo, Formatting.None), ResultCodes.Success, OutputTypes.JSON, True)

                End If
            Catch ex As Exception
                DotNetNuke.Services.Exceptions.LogException(ex)
                Return BuildResult(ex.Message, ResultCodes.FailedWithException, OutputTypes.JSON, False)
            End Try


        End Function
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <param name="username"></param>
        ''' <param name="password"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function AuthenticateUser(ByVal username As String, ByVal password As String) As String
            If String.IsNullOrEmpty(username) And String.IsNullOrEmpty(password) Then
                Return BuildResult(String.Empty, ResultCodes.FailedAuthentication, OutputTypes.JSON, False)
            End If
            Dim auth As New SecureHeader
            auth.Username = username
            auth.Password = password
            auth.AuthToken = String.Empty
            If Not IsUserValid(auth) Then
                Return BuildResult(String.Empty, ResultCodes.FailedAuthentication, OutputTypes.JSON, False)
            End If
            Dim authToken As String = String.Empty
            Dim pc As New DotNetNuke.Security.PortalSecurity
            Dim hsc As New DotNetNuke.Entities.Host.HostSettingsController
            Dim hostGuid As String = hsc.GetHostSetting("GUID").ToString
            authToken = pc.Encrypt(hostGuid, auth.Username.Trim & "|" & auth.Password.Trim)
            Return "[{""success"":true," & Utilities.JSON.Pair("authtoken", authToken) & "}]"

        End Function
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <param name="auth"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function IsUserValid(ByVal auth As SecureHeader) As Boolean
            Init()
            If Not auth Is Nothing Then
                If Not String.IsNullOrEmpty(auth.AuthToken) And String.IsNullOrEmpty(auth.Username) Then
                    Dim authToken As String = String.Empty
                    Dim pc As New DotNetNuke.Security.PortalSecurity
                    Dim hsc As New DotNetNuke.Entities.Host.HostSettingsController
                    Dim hostGuid As String = hsc.GetHostSetting("GUID").ToString
                    authToken = pc.Decrypt(hostGuid, auth.AuthToken)
                    Dim cred() As String = authToken.Split(CChar("|"))
                    auth.Username = cred(0).ToString
                    auth.Password = cred(1).ToString
                End If
                Dim loginStatus As DotNetNuke.Security.Membership.UserLoginStatus
                Dim objUser As DotNetNuke.Entities.Users.UserInfo = DotNetNuke.Entities.Users.UserController.UserLogin(PortalId, auth.Username, auth.Password, String.Empty, PortalName, HttpContext.Current.Request.UserHostAddress, loginStatus, False)
                If loginStatus = DotNetNuke.Security.Membership.UserLoginStatus.LOGIN_SUCCESS Then
                    UserId = objUser.UserID
                    Return ValidateUserId(UserId, PortalId)
                Else
                    Return False
                End If
            Else
                CurrentUser = New UserInfo
                Return False
            End If

        End Function
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <param name="userId"></param>
        ''' <param name="PortalId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend Function ValidateUserId(ByVal userId As Integer, ByVal PortalId As Integer) As Boolean
            Dim uc As New DotNetNuke.Entities.Users.UserController
            Dim objUser As DotNetNuke.Entities.Users.UserInfo = uc.GetUser(PortalId, userId)
            If objUser Is Nothing Then
                CurrentUser = New UserInfo
                Return False
            Else
                Dim dnnforumController As New Controllers.DNNForums
                CurrentUser = dnnforumController.GetUser(PortalId, userId)
                Return True
            End If
        End Function
        
    End Class
End Namespace
